home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Dr. Windows 3
/
dr win3.zip
/
dr win3
/
UTILITY1
/
MSWSRC35.ZIP
/
MEM.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1993-08-28
|
4KB
|
188 lines
/*
* mem.c logo memory management module dvb 6/28/88
*
* Copyright (C) 1989 The Regents of the University of California
* This Software may be copied and distributed for educational,
* research, and not for profit purposes provided that this
* copyright and statement are included in all such copies.
*/
#include "logo.h"
#include "globals.h"
#ifdef ibm
#ifndef __ZTC__
#include <alloc.h>
#endif
#endif
NODE **gcstack;
NODE **gctop;
NODE *free_list = NIL; /* global ptr to free node list */
struct segment *segment_list = NULL; /* global ptr to segment list */
NODETYPES nodetype(NODE *nd)
{
if (nd == NIL) return (PNIL);
return((NODETYPES)nd->node_type);
}
void setobject(NODE *nd, NODE *newobj)
{
NODE *oldobj = getobject(nd);
if (newobj != NIL) increfcnt(newobj);
if (oldobj != NIL && decrefcnt(oldobj) == 0)
gc(oldobj);
nd->n_obj = newobj;
}
void setcar(NODE *nd, NODE *newcar)
{
NODE *oldcar = car(nd);
if (newcar != NIL) increfcnt(newcar);
if (oldcar != NIL && decrefcnt(oldcar) == 0)
gc(oldcar);
nd->n_car = newcar;
}
void setcdr(NODE *nd, NODE *newcdr)
{
NODE *oldcdr = cdr(nd);
if (newcdr != NIL) increfcnt(newcdr);
if (oldcdr != NIL && decrefcnt(oldcdr) == 0)
gc(oldcdr);
nd->n_cdr = newcdr;
}
NODE *_reref(NODE *proc_var, NODE *newval)
{
if (newval != NIL) increfcnt(newval);
if (proc_var != NIL && decrefcnt(proc_var) == 0)
gc(proc_var);
return(newval);
}
NODE *unref(NODE *ret_var)
{
if (ret_var != NIL) decrefcnt(ret_var);
return(ret_var);
}
void addseg()
{
int p;
struct segment *newseg;
// remove for debugging leaks
memory_count++;
if (status_flag) update_status_memory();
if ((newseg = (struct segment *) malloc((size_t)sizeof(struct segment)))
!= NULL) {
newseg->next = segment_list;
segment_list = newseg;
for (p = 0; p < SEG_SIZE; p++) {
newseg->nodes[p].n_cdr = free_list;
free_list = &newseg->nodes[p];
}
}
}
NODE *newnode(NODETYPES type)
{
NODE *newnd;
// include for debugging leaks
// memory_count++;
// if (status_flag) update_status_memory();
if ((newnd = free_list) == NIL) {
addseg();
if ((newnd = free_list) == NIL)
err_logo(OUT_OF_MEM, NIL);
}
free_list = cdr(newnd);
settype(newnd, type);
setrefcnt(newnd, 0);
newnd->n_car = NIL;
newnd->n_cdr = NIL;
newnd->n_obj = NIL;
return(newnd);
}
NODE *cons(NODE *x, NODE *y)
{
NODE *val = newnode(CONS);
setcar(val, x);
setcdr(val, y);
return(val);
}
void gc(NODE *nd)
{
NODE *tcar, *tcdr, *tobj;
int i;
NODE **pp;
for (;;) {
switch (nodetype(nd)) {
case PUNBOUND:
setrefcnt(nd,10000); /* save some time */
case PNIL:
if (gctop == gcstack) return;
nd = *--gctop;
continue;
case LINE:
nd->n_obj = NIL;
case CONS:
case CASEOBJ:
case RUN_PARSE:
case QUOTE:
case COLON:
case TREE:
case CONT:
tcdr = cdr(nd);
tcar = car(nd);
tobj = getobject(nd);
break;
case ARRAY:
pp = getarrptr(nd);
i = getarrdim(nd);
while (--i >= 0) {
tobj = *pp++;
deref(tobj);
// if (tobj != NIL && decrefcnt(tobj) == 0)
// if (gctop < &gcstack[GCMAX])
// *gctop++ = tcdr;
}
free((char *)getarrptr(nd));
tcar = tcdr = tobj = NIL;
break;
case STRING:
case BACKSLASH_STRING:
case VBAR_STRING:
if (getstrhead(nd) != NULL && decstrrefcnt(getstrhead(nd)) == 0)
free(getstrhead(nd));
default:
tcar = tcdr = tobj = NIL;
}
nd->n_cdr = free_list;
free_list = nd;
if (tcdr != NIL && decrefcnt(tcdr) == 0)
if (gctop < &gcstack[GCMAX])
*gctop++ = tcdr;
if (tcar != NIL && decrefcnt(tcar) == 0)
if (gctop < &gcstack[GCMAX])
*gctop++ = tcar;
if (tobj != NIL && decrefcnt(tobj) == 0)
if (gctop < &gcstack[GCMAX])
*gctop++ = tobj;
if (gctop == gcstack) return;
nd = *--gctop;
}
}